﻿using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;

using System.Net;
using System.IO;
using System.Web;
using System.Text;

namespace pnh
{
    class DBInterface
    {
        /// <summary>
        /// url of the server containing the web pages
        /// </summary>
        //const string _serverName = "http://127.0.0.1/Hunter/backdoor/";
        //const string _serverName = "http://www.playnhunt.com/backdoor/";
        const string _serverName = "http://www.eternal-apocalypse.fr/backdoor/";

        //static private string _ftpServerName = "ftp.eternal-apocalypse.fr";

        static private string _ftpURL = "ftp://eternal-apocalypse.fr";
        static private string _ftpUser = "eternala";
        static private string _ftpPwd = "DjnMSkv2";

        /// <summary>
        /// Call a webpage and return the html of that web page
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        static private string request(string url)
        {
            WebResponse objResponse = null;
            bool succeed = false;
            while (!succeed)
            {
                try
                {
                    //request the web page
                    HttpWebRequest objRequest = (HttpWebRequest)System.Net.HttpWebRequest.Create(url);
                    objRequest.UserAgent = "PLAYBOT";
                    objResponse = objRequest.GetResponse();
                    succeed = true;
                }
                catch
                {
                   
                }
            }
            //get the result
            StreamReader sr = new StreamReader(objResponse.GetResponseStream());
            string strResult = sr.ReadToEnd();

            // Close and clean up the StreamReader
            sr.Close();
            
            return strResult;
        }

        /// <summary>
        /// Download a file and save it to the destination
        /// </summary>
        /// <param name="src"></param>
        /// <param name="dest"></param>
        static public bool dowload(string src, string dest)
        {
            try
            {
                WebClient webClient = new WebClient();
                webClient.DownloadFile(src, dest);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Uplaod a file to the ftp server
        /// </summary>
        /// <param name="src">source file</param>
        /// <param name="dest">destination file</param>
        static public bool ftpUpload(string src, string dest)
        {
            //open the file
            FileStream fs = new FileStream(src, FileMode.Open, FileAccess.Read);
            long size = fs.Length;
            byte[] fileContents = new byte[size];
            int res = fs.Read(fileContents, 0, (int)size);
            fs.Close();

            // Get the object used to communicate with the server.
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(dest);
            request.Method = WebRequestMethods.Ftp.UploadFile;
            request.UsePassive = false;
            request.UseBinary = true;
            request.KeepAlive = false;

            // login
            request.Credentials = new NetworkCredential(_ftpUser, _ftpPwd);
            request.ContentLength = fileContents.Length;

            Stream requestStream = null;
            try
            {
                requestStream = request.GetRequestStream();
                requestStream.Write(fileContents, 0, fileContents.Length);
                requestStream.Close();

                FtpWebResponse response = (FtpWebResponse)request.GetResponse();

                //Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);

                response.Close();
                return true;
            }
            catch (Exception e)
            {
                string s = e.Message;
                return false;
            }
            
        }

        static public bool getImg(string src, string dest)
        {
            string imgDest = "./temp.jpg";
            bool res = DBInterface.dowload(src, imgDest);
            if(!res) return false;

            DBInterface.ftpUpload(imgDest, dest);
            return true;
            //File.Delete(imgDest);
        }

        /// <summary>
        /// Create a directory on the ftp server
        /// </summary>
        /// <param name="directory"></param>
        /// <returns></returns>
        public static bool ftpCreateDirectory(string directory)
        {
            WebRequest request = WebRequest.Create(directory);
            request.Method = WebRequestMethods.Ftp.MakeDirectory;
            request.Credentials = new NetworkCredential(_ftpUser, _ftpPwd);
            try
            {
                request.GetResponse();
                return true;
            }
            catch(WebException ex)
            {
                FtpWebResponse response = (FtpWebResponse)ex.Response;
                if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
                {
                    response.Close();
                    return true;
                }
                else
                {
                    response.Close();
                    System.Windows.Forms.MessageBox.Show(ex.Message + "\n" + ex.StackTrace);
                    return false;
                }  
            }
        }

        /// <summary>
        /// Return the number of achievements unlocked by a player for a specific game
        /// </summary>
        /// <param name="playerID"></param>
        /// <param name="gameID"></param>
        /// <returns></returns>
        static public int getAchievementsUnlockedCount(int playerID, int gameID)
        {
            string page = "getAchievementsUnlockedCount.php";
            string url = _serverName + page + "?playerID=" + playerID.ToString() + "&gameID=" + gameID.ToString();

            string res = DBInterface.request(url);
            return int.Parse(res);
        }

        /// <summary>
        /// Update the player gamerscore and return true if the update went well and false if an error occured
        /// </summary>
        /// <param name="playerID"></param>
        /// <param name="gamerscore"></param>
        /// <returns></returns>
        static public bool updatePlayerGamerscore(int playerID, int gamerscore)
        {
            string page = "updatePlayerGamerscore.php";
            string url = _serverName + page + "?playerID=" + playerID.ToString() + "&gamerscore=" + gamerscore.ToString();

            string res = DBInterface.request(url);
            return bool.Parse(res);
        }

        /// <summary>
        /// Update the number of achievements of a game
        /// </summary>
        /// <param name="gameID"></param>
        /// <param name="acheCount"></param>
        /// <returns></returns>
        static public bool updateGameAchievementsCount(int gameID, int acheCount)
        {
            string page = "updateGameAchievementsCount.php";
            string url = _serverName + page + "?gameID=" + gameID.ToString() + "&acheCount=" + acheCount.ToString();

            string res = DBInterface.request(url);
            return bool.Parse(res);
        }

        /// <summary>
        /// Check if a game exists in database
        /// </summary>
        /// <param name="msid"></param>
        /// <returns></returns>
        static public int getGameExists(string msid)
        {
            string page = "getGameExists.php";
            string url = _serverName + page + "?msid=" + msid;
           
            string res = DBInterface.request(url);
            return int.Parse(res);
        }

        /// <summary>
        /// Return the next valid id for a game
        /// </summary>
        /// <returns></returns>
        static public int getNextValidIdForGame()
        {
            string page = "getNextValidIdForGame.php";
            string url = _serverName + page;

            string res = DBInterface.request(url);
            return int.Parse(res);
        }

        /// <summary>
        /// Return the next valid id for an achievement
        /// </summary>
        /// <returns></returns>
        static public int getNextValidIdForAchievement()
        {
            string page = "getNextValidIdForAchievement.php";
            string url = _serverName + page;

            string res = DBInterface.request(url);
                
            return int.Parse(res);     
        }
        
        /// <summary>
        /// Add a game in the database
        /// </summary>
        /// <param name="gameID"></param>
        /// <param name="gameName"></param>
        /// <param name="gameImg"></param>
        /// <param name="gameMsid"></param>
        /// <param name="gameAcheCount"></param>
        /// <returns></returns>
        static public bool addNewGame(int gameID, string gameName, string gameImg, string gameMsid, int gameAcheCount)
        {
            gameName = HttpUtility.UrlEncode(gameName);
            gameImg = HttpUtility.UrlEncode(gameImg);

            getImg(gameImg, Constant.FTP_BOX_IMG + "/" + gameID.ToString() + ".jpg");

            gameImg = HttpUtility.UrlPathEncode(gameImg);
            string page = "addNewGame.php";
            string url = _serverName + page + "?gameID=" + gameID.ToString() + "&gameName=" + gameName + "&gameImg=" + gameImg + "&gameMsid=" + gameMsid + "&gameAcheCount=" + gameAcheCount.ToString();

            string res = DBInterface.request(url);
            return bool.Parse(res);
        }

        /// <summary>
        /// Add an achievement to a game
        /// </summary>
        /// <param name="acheName"></param>
        /// <param name="acheDesc"></param>
        /// <param name="acheImg"></param>
        /// <param name="acheRank"></param>
        /// <param name="gameID"></param>
        /// <returns></returns>
        static public bool addAchievementToGame(int acheID, string acheName, string acheDesc, string acheImg, int acheRank, int gameID)
        {
            //encode the php parameter
            acheName = HttpUtility.UrlEncode(acheName);
            acheDesc = HttpUtility.UrlEncode(acheDesc);
            
            //upload the picture to the ftp
            //getImg(acheImg, "/www/ache_img/"+gameID.ToString()+"/" + acheRank.ToString() + ".jpg");
            getImg(acheImg, Constant.FTP_ACHE_IMG + "/" + gameID.ToString() + "/" + acheRank.ToString() + ".jpg");

            //encode the path
            acheImg = HttpUtility.UrlPathEncode(acheImg);

            //create the url
            string page = "addAchievementToGame.php";
            string url = _serverName + page + "?acheName=" + acheName + "&acheDesc=" + acheDesc + "&acheImg=" + acheImg + "&acheRank=" + acheRank.ToString() + "&gameID=" + gameID.ToString() + "&acheID=" + acheID.ToString();

            //call the page
            string res = DBInterface.request(url);

            //return the result
            return bool.Parse(res);
        }

        /// <summary>
        /// Unlock an achievement for a player
        /// </summary>
        /// <param name="playerID"></param>
        /// <param name="acheID"></param>
        /// <param name="score"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        static public bool addUnlockedAchievement(int playerID, int acheID, int score, DateTime date)
        {
            string page = "addUnlockedAchievement.php";
            string url = _serverName + page;
            if (date != null)
                url = url + "?playerID=" + playerID.ToString() + "&acheID=" + acheID.ToString() + "&score=" + score.ToString() + "&dateDay=" + date.Day.ToString() + "&dateMonth=" + date.Month.ToString() + "&dateYear=" + date.Year.ToString();
            else
                url = url + "?playerID=" + playerID.ToString() + "&acheID=" + acheID.ToString() + "&score=" + score.ToString();
            string res = DBInterface.request(url);
            return bool.Parse(res);
        }

        /// <summary>
        /// Reset the scan_image flag of a player to 0
        /// </summary>
        /// <param name="playerID"></param>
        /// <returns></returns>
        static public bool resetPlayerScanImage(int playerID)
        {
            string page = "resetPlayerScanImage.php";
            string url = _serverName + page;
            url = url + "?playerID=" + playerID.ToString();
            string res = DBInterface.request(url);
            return bool.Parse(res);
        }

        /// <summary>
        /// Check if a player has unlocked an achievement
        /// </summary>
        /// <param name="playerID"></param>
        /// <param name="gameID"></param>
        /// <param name="gameRank"></param>
        /// <returns></returns>
        static public bool getPlayerUnlockedAchievement(int playerID, int gameID, int gameRank)
        {
            string page = "getPlayerUnlockedAchievement.php";
            string url = _serverName + page + "?playerID=" + playerID.ToString() + "&gameID=" + gameID.ToString() + "&acheRank=" + gameRank.ToString();

            string res = DBInterface.request(url);
            return bool.Parse(res);
        }

        /// <summary>
        /// Get the id of an achievement
        /// </summary>
        /// <param name="gameID"></param>
        /// <param name="acheRank"></param>
        /// <returns></returns>
        static public int getAchievementId(int gameID, int acheRank)
        {
            string page = "getAchievementId.php";
            string url = _serverName + page + "?gameID=" + gameID.ToString() + "&acheRank=" + acheRank.ToString();

            string res = DBInterface.request(url);
            return int.Parse(res);
        }

        /// <summary>
        /// Get the number of acihevements for a game
        /// </summary>
        /// <param name="gameID"></param>
        /// <returns></returns>
        static public int getGameAchievementsCount(int gameID)
        {
            string page = "getGameAchievementCount.php";
            string url = _serverName + page + "?gameID=" + gameID.ToString();

            string res = DBInterface.request(url);
            return int.Parse(res);
        }

        /// <summary>
        /// Check if an achievement exists
        /// </summary>
        /// <param name="gameID"></param>
        /// <param name="acheRank"></param>
        /// <returns></returns>
        static public bool getAchievementExists(int gameID, int acheRank)
        {
            string page = "getAchievementExists.php";
            string url = _serverName + page + "?gameID=" + gameID.ToString() + "&acheRank=" + acheRank.ToString();

            string res = DBInterface.request(url);
            return bool.Parse(res);
        }

        /// <summary>
        /// Return the list of player
        /// </summary>
        /// <returns></returns>
        static public string getPlayersList()
        {
            string page = "getPlayersList.php";
            string url = _serverName + page;

            return DBInterface.request(url);
        }

        /// <summary>
        /// Return the list of games
        /// </summary>
        /// <returns></returns>
        static public string getGamesList()
        {
            string page = "getGamesList.php";
            string url = _serverName + page;

            return DBInterface.request(url);
        }

        /// <summary>
        /// Return the list of games with a gamertag
        /// </summary>
        /// <returns></returns>
        static public string getGamesListPerPlayer(int gameIDMax)
        {
            string page = "getGamesListPerPlayer.php?gameID="+gameIDMax.ToString();
            string url = _serverName + page;

            return DBInterface.request(url);
        }
    }
}
